# -*- coding:utf-8 -*-
"""
@Author : 审心
@Time : 2023/5/10 16:45
"""
import math
from dataclasses import dataclass, field

from typing import Optional, Dict, List, Tuple

from DrissionPage import WebPage
from DrissionPage.action_chains import ActionChains
from DrissionPage.chromium_element import ChromiumElement
from DrissionPage.commons.keys import Keys

from autoTask.taobao.ztc.common import WebOperation as commonWebOperation
from autoTask.taobao.ztc.gjc.OptiBid import WebOperation
from autoTask.taobao.ztc.gjc.OptiBid.Enum import TbType
from autoTask.taobao.ztc.gjc.OptiBid.WebOperation import AM
from autoTask.taobao.ztc.gjc.OptiBid.pojo import TaskParam, FilterRule
from common.utils import ObjUtil
from common.utils.web_page_util import Tap, Input, get_first_visible_ele
from common.logger.log import log_


@dataclass
class Main:
    """
    优化关键词出价任务
    Attributes:
        p(WebPage) : 网页对象
        task_param_list: 过滤条件以及结果判断参数
        bid_scope : 关键词出价区间
        premium_scope: 溢价出价区间
        is_update_gjc: 是否更新关键词出价
        is_update_rq: 是否更新人群出价
        is_test_execute: 是否测试执行
    """
    p: Optional[WebPage] = None
    task_param_list: List[TaskParam] = field(default_factory=list)
    bid_scope: Tuple[float, float] = (0.05, 99.9)
    premium_scope: Tuple[float, float] = (5, 300)
    is_update_gjc: bool = True
    is_update_rq: bool = True
    is_test_execute: bool = True

    def __call__(self, p: WebPage):
        self.p = p
        cycle_list = ['过去7天', '过去14天', '过去30天', '过去90天']
        # 前往直通车首页
        commonWebOperation.goto_index(self.p)
        # 打开阿明工具首页
        WebOperation.AM.open_view(self.p)
        for param in self.task_param_list:
            if self.is_update_gjc:
                # 前往关键词优化标签页
                WebOperation.AM.goto_gjc_tag(self.p)
                # 初始化模板高级筛选
                WebOperation.AM.init_filter_template(self.p, TbType.GJC.value, param.filter_rule_list)
                for c_index, cycle in enumerate(cycle_list):
                    # 设置数据周期以及模板过滤数据
                    WebOperation.AM.set_filter_template(self.p, cycle, 1)
                    # 设置出价
                    self.set_bid(tb_type=TbType.GJC.value, adjust_percentage=param.cycle_adjust_percentage[c_index])
            if self.is_update_rq:
                # 前往人群优化标签页
                WebOperation.AM.goto_rq_tag(self.p)
                # 初始化模板高级筛选
                WebOperation.AM.init_filter_template(self.p, 2, param.filter_rule_list)
                for c_index, cycle in enumerate(cycle_list):
                    # 设置数据周期以及模板过滤数据
                    WebOperation.AM.set_filter_template(self.p, cycle, 2)
                    # 设置溢价
                    self.set_bid(tb_type=TbType.RQ.value, adjust_percentage=param.cycle_adjust_percentage[c_index])

    def call_v2(self, p: WebPage):
        self.p = p
        cycle_list = ['过去7天', '过去14天', '过去30天', '过去90天']
        # 前往直通车首页
        commonWebOperation.goto_index(self.p)
        # 打开阿明工具首页
        WebOperation.AM.open_view(self.p)
        for param in self.task_param_list:
            if self.is_update_gjc:
                # 前往关键词优化标签页
                WebOperation.AM.goto_gjc_tag(self.p)
                # 初始化模板高级筛选
                WebOperation.AM.init_filter_template(self.p, TbType.GJC.value, param.filter_rule_list)
                for c_index, cycle in enumerate(cycle_list):
                    self.set_gjc_bid_v2(adjust_percentage=param.cycle_adjust_percentage[c_index], cycle=cycle)

    @staticmethod
    def init_by_params(params: Dict):
        task_param_list = params.get("markTemplateList")
        task_param_list = [TaskParam(item.get('cycleAdjustPercentage'),
                                     filter_rule_list=[ObjUtil.from_dict(sub_item, FilterRule) for sub_item in
                                                       item.get('filterList')])
                           for item in task_param_list]
        return Main(
            task_param_list=task_param_list,
            bid_scope=params.get("bidScope"),
            premium_scope=params.get("premiumScope"),
            is_update_gjc=params.get("isUpdateGjc"),
            is_update_rq=params.get("isUpdateRq")
        )

    def set_gjc_bid_v2(self, adjust_percentage: int, cycle: str):
        """
        设置关键词出价 v2版本 (通过全选提高修改效率)
        :param adjust_percentage: 当前周期需要调整的百分比
        :param cycle: 当前周期的字符串 用于切换表格数据周期
        :return:
        """
        # 是否为正数
        is_positive_number = adjust_percentage >= 0
        Tap(self.p("t:span@@text()=仅词包"), "选择仅词包", by_js=True)()
        WebOperation.AM.set_filter_template(self.p, cycle, TbType.GJC.value)
        count = AM.get_tb_data_count(self.p, TbType.GJC.value)
        if count > 0:
            WebOperation.AM.tb_select_all(self.p)
            Tap(AM.get_tb_ele(self.p, TbType.GJC.value)(".operate-group")("tx:修改出价"), by_js=True)()
            e = self.p.eles("tx:提高出价")[1] if is_positive_number else self.p.eles("tx:降低出价")[1]
            Tap(e, "点击调整价格输入框")()
            Input(e("t:input"), "输入新出价失败", vals=abs(adjust_percentage), after_delay=1)()
            if self.is_test_execute:
                Tap(get_first_visible_ele(self.p, "t:span@text():取 消"), by_js=True, after_delay=3)()
            else:
                Tap(get_first_visible_ele(self.p, "t:span@text():确 定"), by_js=True, after_delay=3)()
            log_.info(f"关键词 词包调整出价 {adjust_percentage} 百分比")

        Tap(self.p("t:span@@text()=仅关键词"), "选择仅关键词", by_js=True)()
        WebOperation.AM.set_filter_template(self.p, cycle, TbType.GJC.value)
        count = AM.get_tb_data_count(self.p, TbType.GJC.value)
        if count > 0:
            WebOperation.AM.tb_select_all(self.p)
            Tap(AM.get_tb_ele(self.p, TbType.GJC.value)(".operate-group")("tx:修改出价"), by_js=True)()
            input_es = self.p("tx:+/- 出价百分比").next().eles("t:input")
            Tap(input_es[0], by_js=True, after_delay=3)()
            Tap(get_first_visible_ele(self.p, f"t:li@@text()={'+' if is_positive_number else '-'}"), by_js=True)()
            Tap(input_es[0], by_js=True, after_delay=1)()
            Input(input_es[1], msg="输入出价操作百分比", vals=abs(adjust_percentage), after_delay=1)()
            if self.is_test_execute:
                Tap(get_first_visible_ele(self.p, "t:span@text():取 消"), by_js=True, after_delay=3)()
            else:
                Tap(get_first_visible_ele(self.p, "t:span@text():确 定"), by_js=True, after_delay=3)()
            log_.info(f"关键词调整出价 {adjust_percentage} 百分比")

    def set_bid(self, tb_type: int, adjust_percentage: int):
        """
        设置当前表格关键词出价
        :param tb_type 表格类型 1 关键词 2 人群
        :param adjust_percentage 调整价格百分比
        :return:
        """
        log_.info("开始设置当前表格出价或溢价")
        tb_ele = WebOperation.AM.get_tb_ele(self.p, tb_type)("c:.yqs-common-table > .el-table__body-wrapper")
        tb_ele.scroll.to_top()
        # 获取总行数
        total = WebOperation.AM.get_tb_data_count(self.p, tb_type)
        if total == 0:
            return
        # 估计一个页数 假设一页就5条新数据
        pages = total / 5
        log_.info(f"表格数据总行数 : {total}")
        # 已经操作过的行号
        use_update_row = []
        # 当前页码
        use_pages = 0

        while total > len(use_update_row) and use_pages < pages:
            tb = WebOperation.AM.get_tb_ele(self.p, tb_type)
            rows = tb(".el-table__fixed-body-wrapper")('t:table@@class=el-table__body') \
                .eles(".el-table__row")
            # 鼠标滚动一次翻页距离
            w, mouse_scroll_y_px = rows[0].size
            for row in rows:
                cols = row.eles("t:td")
                if cols[0].text not in use_update_row:
                    # 修改关键词出价操作
                    cell = None
                    if tb_type == TbType.GJC.value:
                        cell = cols[8]
                    elif tb_type == TbType.RQ.value:
                        cell = cols[6]
                    self.update_bid_operation(cell, tb_type, adjust_percentage)
                    use_update_row.append(cols[0].text)
            log_.info(f"已经修改过价格的行数 : {len(use_update_row)}")
            if total <= len(use_update_row):
                break
            # 滚动翻页
            ActionChains(self.p).move_to(rows[len(rows) - 1])
            tb_ele.scroll.down(mouse_scroll_y_px * 5)
            use_pages += 1
        log_.info("当前表格出价设置成功")

    def update_bid_operation(self, bid_ele: ChromiumElement, tb_type: int, adjust_percentage: int):
        """
        修改出价操作
        :param bid_ele: 出价单元格元素
        :param tb_type: 表格类型 1 关键词 2 人群
        :param adjust_percentage: 操作价格百分比
        :return:
        """
        bid_ele.hover()
        Tap(bid_ele("t:i"), "点击编辑出价图标", is_random=False, before_delay=2)()
        if tb_type == TbType.GJC.value:
            # 计算一下价格
            old_bid = float(bid_ele(".t-t-text").text.replace('元', '').strip())
            new_bid = old_bid if adjust_percentage == 0 else round(old_bid + old_bid * (adjust_percentage / 100), 2)
            if new_bid < self.bid_scope[0]:
                new_bid = self.bid_scope[0]
            elif new_bid > self.bid_scope[1]:
                new_bid = self.bid_scope[1]
            WebOperation.AM.set_gjc_bid(self.p, new_bid, self.is_test_execute)
            log_.info(f"原出价 : {old_bid} 新出价 : {new_bid} 调整百分比 : {adjust_percentage}")
        elif tb_type == TbType.RQ.value:
            # 计算溢价
            old_premium = int(bid_ele(".t-t-text").text.replace('%', '').strip())
            new_premium = int(math.ceil(old_premium + old_premium * (adjust_percentage / 100)))
            if new_premium < self.premium_scope[0]:
                new_premium = self.premium_scope[0]
            elif new_premium > self.premium_scope[1]:
                new_premium = self.premium_scope[1]
            WebOperation.AM.set_rq_bid(self.p, new_premium, self.is_test_execute)
            log_.info(f"原溢价 : {old_premium} 新溢价 : {new_premium} 调整百分比 : {adjust_percentage}")
